﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.Concurrent;
using Atom.NetFrame;
using Atom.Tool;
using Protocol;

namespace Atom.Logic.Select
{
    public class SelectHandle : AbsOnceHandler, HandleInterface
    {

        /// <summary>
        /// 多线程处理类中  防止数据竞争导致脏数据  使用线程安全字典
        /// 玩家所在匹配房间映射
        /// </summary>
        ConcurrentDictionary<int, int> userRoom = new ConcurrentDictionary<int, int>();
        /// <summary>
        /// 房间id与模型映射
        /// </summary>
        ConcurrentDictionary<int, SelectRoom> roomMap = new ConcurrentDictionary<int, SelectRoom>();
        /// <summary>
        /// 回收利用过的房间对象再次利用，减少gc性能开销
        /// </summary>
        ConcurrentStack<SelectRoom> cache = new ConcurrentStack<SelectRoom>();
        /// <summary>
        /// 区域码
        /// </summary>
        ConcurrentInteger index = new ConcurrentInteger();

        public SelectHandle()
        {
            EventUtil.CreateSelect = Create;
            EventUtil.DestorySelect = Destory;
        }



        public void ClientClose(UserToken ut, string error)
        {
            int userId = GetUserID(ut);
            if (userRoom.ContainsKey(userId))
            {
                int roomId = userRoom[userId];
                if(roomMap.ContainsKey(roomId))
                {
                    SelectRoom room = roomMap[roomId];
                    room.ClientClose(ut, error);
                }
                int i;
                userRoom.TryRemove(userId, out i);
            }
        }

        public void ClientConnect(UserToken ut)
        {

        }

        public void MessageReceive(UserToken ut, SocketModel message)
        {
            int userId = GetUserID(ut);
            if (userRoom.ContainsKey(userId))
            {
                int roomId = userRoom[userId];
                if (roomMap.ContainsKey(roomId))
                {
                    SelectRoom room = roomMap[roomId];
                    room.MessageReceive(ut, message);
                }
            }

        }

        private void Create(List<int> teamOne, List<int> teamTwo)
        {
            SelectRoom room = null;
            if (cache.Count > 0)
            {
                cache.TryPop(out room);
            }
            else
            {
                room = new SelectRoom();
                //设置房间的唯一区域码
                room.SetArea(index.GetAndAdd());
            }
            room.Init(teamOne, teamTwo);
            foreach (int item in teamOne)
            {
                userRoom.TryAdd(item, room.GetArea());
            }
            foreach (int item in teamTwo)
            {
                userRoom.TryAdd(item, room.GetArea());
            }
            roomMap.TryAdd(room.GetArea(), room);

        }

        private void Destory(int roomID)
        {
            SelectRoom room;
            if(roomMap.TryRemove(roomID,out room))
            {
                //移除角色和房间的队列
                int temp = 0;
                foreach (int item in room.teamOne.Keys)
                {
                    userRoom.TryRemove(item, out temp);
                }
                foreach (int item in room.teamTwo.Keys)
                {
                    userRoom.TryRemove(item, out temp);
                }
                //移除房间的所有数据
                room.Tokens.Clear();
                room.teamOne.Clear();
                room.teamTwo.Clear();
                room.readList.Clear();
                //d丢入缓存队列
                cache.Push(room);
            }
        }

        public override byte Gettype()
        {
            return GameProtocol.TYPE_SELECT;
        }

        public override int GetArea()
        {
            return 0;
        }
    }
}
